#include "MemoryMenagerGraphics.h"
#include "screen.h"
#include <string.h>
#include <math.h>
#include <conio.h>

#define DOT1 0xffffffb0
#define DOT2 0xffffffb1
#define DOT3 0xffffffb2

const int STARTX = 2;
const int ENDX  = 78;
const int STARTY = 1;

MemoryMenagerGraphics::MemoryMenagerGraphics(char * filename) : MemoryMenager(filename)
{
char tmp[100];
fstream myfile(filename,ios::in);

	CommandsCount = 0;
	while (!myfile.eof())
	{
		myfile.getline(tmp,100);
		CommandsCount++;
	}
	
	myfile.close();
	
}

MemoryMenagerGraphics::~MemoryMenagerGraphics(void)
{
	
}

void MemoryMenagerGraphics::Initalize()
{
	screen::showcursor(false);
	screen::fillascii(0,0,79,24,' ',0x1f);// blue background
	screen::fillascii(0,0,79,0,' ',0x7f);
	screen::fillascii(0,24,79,24,' ',0x7f);
	screen::puttext("Memory Manager 2010 By Jazzy & AfterMath",2,0,0x70);
	screen::puttext("| JazzySoft Memory Manager 2010",48,24,0x70);
	screen::puttext(" Press ESQ To Quit ",59,0,0x0f);
	screen::boxex("Pointers Status ",2,16,39,22,BT_ONE,0x1f,0x00);
	screen::fillascii(2,23,35,23,(char)DOT2,0x1f);
	screen::boxex(" Symbol ",41,16,77,23,BT_ONE,0x1f,0x00);

	DrawFree(43,17);		 screen::puttext(" - Free",45,17,0x17);
	DrawSize(43,19,false);   screen::puttext(" - Size",45,19,0x17);
	DrawPointer(43,21);		 screen::puttext(" - Pointer",45,21,0x17);

	DrawFull(64,17);		screen::puttext(" - Full",66,17,0x17);
	DrawUnused(64,19);		screen::puttext(" - Unused",66,19,0x17);
	DrawSize(64,21,true);   screen::puttext(" - Last",66,21,0x17);

}
void MemoryMenagerGraphics::DrawFree(int x, int y)const
{
	screen::putchar((char)DOT2,x,y,0x1f);
}
void MemoryMenagerGraphics::DrawSize(int x, int y,bool last)const
{
	if (last)
	 screen::putchar((char)DOT1,x,y,0xa1);
	else
	 screen::putchar((char)DOT1,x,y,0xe1);
}
void MemoryMenagerGraphics::DrawPointer(int x, int y)const
{
screen::putchar((char)DOT3,x,y,0x1c);
}
void MemoryMenagerGraphics::DrawFull(int x, int y)const
{
screen::putchar((char)DOT2,x,y,0x1e);
}
void MemoryMenagerGraphics::DrawUnused(int x,int y) const
{
screen::putchar('X',x,y,0x1e);
}
void MemoryMenagerGraphics::DrawMemory() 
{
int index=0,inner=0;
int i_size,i_pointer;
int x=STARTX,y=STARTY;


while (index+1 < 1000)
{
	i_size    =  Memory[index];
	i_pointer =  Memory[index + 1];

	if (i_size==UNUSEDBLOCK)
	{
		DrawUnused(x,y);
		UpdateXY(x,y);
		index++;
		continue; //if unused block found, draw it and start from next block
	}

	DrawSize(x,y,i_size + index >= 1000); //draw size block
	UpdateXY(x,y);

	if (i_pointer!=0) //if pointer exist, this is free block,draw pointer
	{
	DrawPointer(x,y);
	UpdateXY(x,y);
	}
	
	for(inner = (i_pointer==0)?(0):(1);inner<i_size;inner++)
	{
		//full is when (pointer=0) and (not last free block) (=because his pointer also 0)
		if ((i_pointer==0) && !(i_size + index >= 1000) )
			DrawFull(x,y);
		else
			DrawFree(x,y);
	
		UpdateXY(x,y);

	}
	// increase to the next block
	index = index + i_size + 1;

}

screen::fillascii(4,17,38,21,' ',0x1f);
for(inner = 0;inner < pFreeList.getListCount();inner++)
{
	screen::puttext("Free Block [ ]:Index=   ,Size=   ",4,17+inner,0x17);
	screen::puttext(inner,16,17+inner,0x17);
	screen::puttext(pFreeList[inner]->getMemoryIndex(),25,17+inner,0x1e);
	screen::puttext(pFreeList[inner]->getBlockSize(),34,17+inner,0x1d);

}

}

void MemoryMenagerGraphics::Draw() 
{
	DrawStatusBar(CurrentIndex);
	DrawMemory();
}
void MemoryMenagerGraphics::UpdateXY(int &x,int &y)
{
x++;
if (x>=ENDX)
	{
		x = STARTX;
		y++;
	}
}

void MemoryMenagerGraphics::DrawStatusBar(int ind)
{
double rel,per;
rel = ((33.0) * (float)ind) / (float)CommandsCount;
rel = floor(rel + 0.5);
screen::fillascii(2,23,2+(int)rel,23,(char)DOT2,0x1a);

per = ((100.0) * (float)ind) / (float)CommandsCount;
screen::puttext((int)per,36,23,0x1a);
screen::puttext("%",(per<10)?(37):( (per<100)?(38):(39) ),23,0x1a);

screen::puttext("Action:                   ",2,24,0x70);
screen::puttext(CurrentAction,10,24,0x71);
}

void MemoryMenagerGraphics::Finalize()
{
	screen::puttext(" Process Ended. ",0,24,0x07);
	getch();
}